from peewee import *
from src.models.BaseModel import BaseModel
from src.entry.Entrys import Page
from src.util.Model2Dict import m2d

""" 系统所有的菜单 """


class Menu(BaseModel):
    mId = BigIntegerField(db_column='m_id', primary_key=True)
    parent = BigIntegerField(db_column='parent')
    key = CharField(db_column='key')
    name = CharField(db_column='name')
    icon = CharField(db_column='icon')
    iconType = CharField(db_column='icon_type')
    path = CharField(db_column='path')
    component = CharField(db_column='component')
    createTime = DateTimeField(db_column='create_time')
    status = CharField(db_column='status')
    faceShow = CharField(db_column='face_show')
    sort = IntegerField()

    # 设置模型对应的数据库表名
    class Meta:
        table_name = 'sys_menu'

    # 分页查询菜单
    @staticmethod
    def getAllMenu(page: Page = Page()):
        r = Menu.select().paginate(page.num, page.size).dicts()
        page.count = Menu.select().count()
        page.rows = m2d(r)
        return page.__dict__

    # 获取所有菜单
    @staticmethod
    def getAllMenus():
        r = Menu.select().dicts()
        return m2d(r)

    # 获取所有菜单名
    @staticmethod
    def getAllMenuName(page: Page = Page()):
        r = Menu.select(Menu.mId, Menu.name).paginate(page.num, page.size).dicts()
        page.count = Menu.select().count()
        page.rows = m2d(r)
        return page.__dict__

    # 更新菜单数据
    @staticmethod
    def updateMenu(m_id: int, k):
        return Menu.update(k).where(Menu.mId == m_id).execute() > 0

    # 根据获取 id 在ids 的所有菜单
    @staticmethod
    def getMenusInMIds(mids: list[int]):
        ms = Menu.select().where(Menu.mId.in_(mids)).dicts()
        return m2d(ms)

    # 获取所有parent在id集合里的菜单
    @staticmethod
    def getMenusInPids(mids: list[int]):
        return m2d(Menu.select().where(Menu.parent.in_(mids)).dicts())

    # 查询所选菜单是否拥有子菜单
    @staticmethod
    def MenuHasChild(mids: list[int]):
        return Menu.select().where(Menu.parent.in_(mids)).count() > 0

    # 根据菜单id 删除菜单
    @staticmethod
    def delMenuInMId(mid: list[int]):
        return Menu.delete().where(Menu.mId.in_(mid)).execute() > 0

    # 根据父菜单删除菜单
    @staticmethod
    def delMenuInPid(id: list[int]):
        return Menu.delete().where(Menu.parent.in_(id)).execute() > 0

    # 添加菜单
    @staticmethod
    def addMenu(k) -> int:
        return Menu.insert(k).execute()

    # 查询菜单是否存在
    @staticmethod
    def hasMenu(mid) -> bool:
        return Menu.select(Menu.mId).where(Menu.mId == mid).count() > 0


""" 系统接口表 """


class SysHandle(BaseModel):
    hId = BigIntegerField(db_column='h_id', primary_key=True)
    name = CharField(db_column='name')
    key = CharField(db_column='key')
    path = CharField(db_column='path')
    method = CharField(db_column='method')
    status = CharField(db_column='status')
    log = CharField()
    type = CharField()

    class Meta:
        table_name = 'sys_handle'

    # 查询接口是否存在
    @staticmethod
    def hasHandle(hid) -> bool:
        return SysHandle.select(SysHandle.hId).where(SysHandle.hId == hid).count() > 0

    # 根据路径已经接口方法查询菜单是否存在
    @staticmethod
    def hasHandleByPathMethod(path: str, method: str):
        return SysHandle.select(SysHandle.hId).where(SysHandle.path == path, SysHandle.method == method).count() > 0

    # 查询是菜单是否存在且可用
    @staticmethod
    def hasCanUseHandleByPathMethod(path: str, method: str):
        return SysHandle.select(SysHandle.hId).where(SysHandle.path == path, SysHandle.method == method,
                                                     SysHandle.status == '1').count() > 0

    # h_ids 限制接口范围 分页获取接口
    @staticmethod
    def getAllHandle(page: Page = Page(), cdn: dict = None, h_ids: list[int] = None):
        if cdn is None:
            cdn = dict()
        query = SysHandle.select()
        if h_ids is not None:
            query = query.where(SysHandle.hId.in_(h_ids))
        if cdn.get('path'):
            query = query.where(SysHandle.path.startswith(cdn.get('path')))
        if cdn.get('method'):
            query = query.where(SysHandle.method == cdn.get('method'))
        if cdn.get('key'):
            query = query.where(SysHandle.key == cdn.get('key'))
        if cdn.get('type'):
            query = query.where(SysHandle.type == cdn.get('type'))
        if cdn.get('status'):
            query = query.where(SysHandle.status == cdn.get('status'))
        if cdn.get('name'):
            query = query.where(SysHandle.name.contains(cdn.get('name')))
        r = query.paginate(page.num, page.size).dicts()
        page.count = query.count()
        page.rows = m2d(r)
        return page.__dict__

    # 获取系统接口名
    @staticmethod
    def getAllHandleName(page: Page = Page(), cdn=None):
        if cdn is None:
            cdn = dict()
        query = SysHandle.select(SysHandle.name, SysHandle.hId)
        if cdn.get("path"):
            query = query.where(SysHandle.path.startswith(cdn.get('path')))
        if cdn.get("method"):
            query = query.where(SysHandle.method == cdn.get('method'))
        if cdn.get('key'):
            query = query.where(SysHandle.key == cdn.get('key'))
        if cdn.get('type'):
            query = query.where(SysHandle.type == cdn.get('type'))
        if cdn.get('status'):
            query = query.where(SysHandle.status == cdn.get('status'))
        if cdn.get('name'):
            query = query.where(SysHandle.name.contains(cdn.get('name')))
        r = query.paginate(page.num, page.size).dicts()
        page.count = query.count()
        page.rows = m2d(r)
        return page.__dict__

    # 更新接口数据
    @staticmethod
    def updateHandle(h_id: list[int], k):
        SysHandle.update(k).where(SysHandle.hId.in_(h_id)).execute()
        return True

    # 根据id 查询接口
    @staticmethod
    def getHandlesInId(ids: list):
        r = SysHandle.select().where(SysHandle.hId.in_(ids)).dicts()
        return m2d(r)

    # 更具类型查询相应类型下的所有 接口id
    @staticmethod
    def getHandleNameByType(h_type: str):
        r = SysHandle.select(SysHandle.hId, SysHandle.name).where(SysHandle.type == h_type).dicts()
        return m2d(r)

    # 根据系统接口列表删除系统接口
    @staticmethod
    def delHandleInId(h_ids: list[int]):
        return SysHandle.delete().where(SysHandle.hId.in_(h_ids)).execute() > 0

    # 添加系统接口
    @staticmethod
    def addHandle(k) -> int:
        return SysHandle.insert(k).execute()

    # 根据接口路径以及接口方法获取系统接口
    @staticmethod
    def getHandleByPathAndMethod(path: str or None, method: str):
        if path is None:
            return None
        r = SysHandle.select().where(SysHandle.path == path, SysHandle.method == method).dicts()
        if len(r) > 0:
            return m2d(r)[0]
        return None

    # 根据接口路径获取能够使用的系统接口id
    @staticmethod
    def HandleCanUseIdByPath(path: str):
        r = SysHandle.select(SysHandle.hId).where(SysHandle.path == path, SysHandle.status == '1').dicts()
        if len(r) > 0:
            return m2d(r)[0]["hId"]
        return None

    # 根据path获取SysHandle表的handleName属性用于日志
    @staticmethod
    def getHandleByPath(path):
        r = m2d(SysHandle.select().where(SysHandle.path == path).dicts())
        if len(r) > 0:
            return r[0]
        return None


# 菜单按钮表
class MenuButton(BaseModel):
    hId = BigIntegerField(db_column='h_id')
    mId = IntegerField(db_column='m_id')
    status = CharField(db_column='status')
    show = CharField(db_column='show')
    tag = CharField(primary_key=True)
    icon = CharField()
    type = CharField()
    style = CharField()
    iconType = CharField(db_column='icon_type')
    name = CharField(db_column='name')

    class Meta:
        table_name = 'sys_menu_button'

    # 根据 菜单id 查询 菜单上所有的按钮id
    @staticmethod
    def getAllMenuHandleTags(mid: list[int]) -> list[str]:
        r = MenuButton.select(MenuButton.tag).where(MenuButton.mId.in_(mid)).dicts()
        return [item['tag'] for item in m2d(r)]

    # 根据菜单获取所有的菜单按钮
    @staticmethod
    def getAllMenuHandleInMids(mids: list[int]):
        r = MenuButton.select().where(MenuButton.mId.in_(mids)).dicts()
        return m2d(r)

    # 删除所有菜单按钮和系统接口的映射关系
    @staticmethod
    def delMenuHandleInHid(hid: list[int]):
        return MenuButton.delete().where(MenuButton.hId.in_(hid)).execute()

    # 删除某个菜单的所有按钮
    @staticmethod
    def delMenuHandleInMid(mid: list[int]):
        count = MenuButton.delete().where(MenuButton.mId.in_(mid)).execute()
        if count > 0:
            return True
        return False

    # 查询菜单是否拥有某(接口)按钮权限
    @staticmethod
    def hasMenuHandle(tag: str) -> bool:
        if MenuButton.select(MenuButton.hId).where(MenuButton.tag == tag).count() > 0:
            return True
        return False

    # 为用户添加菜单
    @staticmethod
    def addMenuHandle(mhs: list[dict]):
        MenuButton.insert_many(mhs).execute()
        return True
